import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

/**
 *  The ButtonColumn class provides a renderer and an editor that looks like a
 *  JButton. The renderer and editor will then be used for a specified column
 *  in the table. The TableModel will contain the String to be displayed on
 *  the button.
 *
 *  The button can be invoked by a mouse click or by pressing the space bar
 *  when the cell has focus. Optionally a mnemonic can be set to invoke the
 *  button. When the button is invoked the provided Action is invoked. The
 *  source of the Action will be the table. The action command will contain
 *  the model row number of the button that was clicked.
 *
 */
public class ButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
{
    private JTable table;
    private ActionListener action;
    private Border originalBorder;
    private Border focusBorder;

    private JButton renderButton;
    private JButton editButton;
    private Object editorValue;
    private boolean isButtonColumnEditor;

    /**
     *  Create the ButtonColumn to be used as a renderer and editor. The
     *  renderer and editor will automatically be installed on the TableColumn
     *  of the specified column.
     *
     *  @param table the table containing the button renderer/editor
     *  @param action the Action to be invoked when the button is invoked
     *  @param column the column to which the button renderer/editor is added
     */
    public ButtonColumn(JTable table, ActionListener action, int column)
    {
        this.table = table;
        this.action = action;

        renderButton = new JButton();
        editButton = new JButton();
        editButton.addActionListener(this);
        
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(column).setCellRenderer(this);
        columnModel.getColumn(column).setCellEditor(this);
        table.addMouseListener(this);
    }
//
//  Implement TableCellEditor interface
//    
    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
    {
        if (value == null)
        {
            editButton.setText("");
            editButton.setIcon(null);
        }
        else if (value instanceof Icon)
        {
            editButton.setText("");
            editButton.setIcon((Icon)value);
        }
        else
        {
            editButton.setText(value.toString());
            editButton.setIcon(null);
        }
        this.editorValue = value;
        return editButton;
    }

    @Override
    public Object getCellEditorValue()
    {
        return editorValue;
    }
//
//  Implement TableCellRenderer interface
//
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        if (isSelected)
        {
            renderButton.setForeground(table.getSelectionForeground());
            renderButton.setBackground(table.getSelectionBackground());
        }
        else
        {
            renderButton.setForeground(table.getForeground());
            renderButton.setBackground(UIManager.getColor("Button.background"));
        }

        if (hasFocus)
        {
            renderButton.setBorder(focusBorder);
        }
        else
        {
            renderButton.setBorder(originalBorder);
        }
        if (value == null)
        {
            renderButton.setText("");
            renderButton.setIcon(null);
        }
        else if (value instanceof Icon)
        {
            renderButton.setText("");
            renderButton.setIcon((Icon)value);
        }
        else
        {
            renderButton.setText(value.toString());
            renderButton.setIcon(null);
        }
        return renderButton;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if(editorValue != null)
        {
            int row = table.convertRowIndexToModel(table.getEditingRow());
            fireEditingStopped();

            ActionEvent event = new ActionEvent(table,ActionEvent.ACTION_PERFORMED,"" + row);
            action.actionPerformed(event);
        }
    }
//
//  Implement MouseListener interface
//
    @Override
    public void mousePressed(MouseEvent e)
    {
    	if (table.isEditing() && table.getCellEditor() == this)
        {
            isButtonColumnEditor = true;
        }
    }
    @Override
    public void mouseReleased(MouseEvent e)
    {
    	if (isButtonColumnEditor && table.isEditing())
        {
            table.getCellEditor().stopCellEditing();
        }
        isButtonColumnEditor = false;
    }
    @Override
    public void mouseClicked(MouseEvent e) {}
    @Override
    public void mouseEntered(MouseEvent e) {}
    @Override
    public void mouseExited(MouseEvent e) {}
}
